package com.swak.reactivex.cluster;

import java.net.InetSocketAddress;
import java.util.concurrent.CompletableFuture;

import com.swak.exception.RemotingException;

/**
 * Member.
 * 
 * @author 618lf
 */
public interface Member {

	/**
	 * 当前服务ID
	 * 
	 * @return
	 */
	ID id();

	/**
	 * 当前的服务
	 * 
	 * @return
	 */
	boolean isThis();

	/**
	 * 服务集群
	 * 
	 * @return
	 */
	Members members();

	/**
	 * 持有的连接
	 * 
	 * @return
	 */
	Channels channels();

	/**
	 * 服务地址（单播地址）
	 * 
	 * @return
	 */
	InetSocketAddress address();

	/**
	 * 通过 Tcp 发送消息:
	 * 
	 * 1. 如果是服务端实例，则会将消息群发到所有的其他服务
	 * 2. 如果是客户端实例，则会将消息单发到指定的其他服务
	 * @param message
	 * @throws RemotingException
	 */
	void send(Object message) throws RemotingException;

	/**
	 * 通过 Tcp 发送消息:
	 * 
	 * 1. select 出一个连接来发送消息.
	 * 
	 * @param message
	 * @throws RemotingException
	 */
	CompletableFuture<Object> request(Object request) throws RemotingException;

	/**
	 * 通过 Udp 发送消息: 不会发送给自己
	 * 
	 * 1. 如果是服务端实例，则会将消息群发到所有的其他服务
	 * 2. 如果是客户端实例，则会将消息单发到指定的其他服务
	 * @param message
	 * @throws RemotingException
	 */
	void broadcast(Object message) throws RemotingException;

	/**
	 * 通过 Udp 发送消息:
	 * 
	 * 1. 发送一个udp数据报到指定的服务器
	 * 
	 * @param address
	 * @param message
	 */
	void broadcast(InetSocketAddress address, Object message) throws RemotingException;

	/**
	 * 通过 Udp 发送消息:
	 * 
	 * 1. 发送一个udp数据报到指定的服务器.
	 * 2. 需要有返回值，但是 udp 是不可靠的.
	 * 
	 * @param address
	 * @param message
	 */
	CompletableFuture<Object> request(InetSocketAddress address, Object request) throws RemotingException;

	/**
	 * 官博当前服务，退出集群.
	 */
	void close();
}